package app.engine.mc;

import app.engine.entitys.Move;
import app.engine.enums.MoveScoreAttackType;
import app.engine.enums.MoveScoreDefenseType;
import app.game.ChessPoint;
import app.game.enums.Chess;
import app.game.enums.Direction;

import java.util.ArrayList;
import java.util.List;

import static app.ui.Config.BOARD_LINE;

public class SearchHelper {

    /**
     * 走法生成
     * @param chessBoard
     * @param nowChess
     * @return
     */
    public static List<Move> getMoves(Chess[][] chessBoard, Chess nowChess) {
        List<Move> moves = new ArrayList<>();
        for (int i = 0; i < BOARD_LINE; i++) {
            for (int j = 0; j < BOARD_LINE; j++) {
                if (chessBoard[i][j] == Chess.EMPTY) {
                    Move move = new Move(i, j, 0);
                    chessBoard[move.getX()][move.getY()] = nowChess;
                    int score = SearchHelper.getMoveScore(new ChessPoint(i, j), chessBoard, nowChess);
                    chessBoard[move.getX()][move.getY()] = Chess.EMPTY;
                    move.setScore(score);
                    // 去掉0分
                    if (score > 0){
                        //System.out.println("局面生成走法["+i+", "+j+"]，评分为"+ score);
                        moves.add(move);
                    }

                }

            }
        }
        return moves;
    }
    /**
     * 走法评分
     * @param nowPoint
     * @param chessBoard
     * @param nowChess
     * @return
     */
    private static int getMoveScore(ChessPoint nowPoint, Chess[][] chessBoard, Chess nowChess) {
        int totalScore = 0;
        Direction[] directions = Direction.values();
        for (Direction direction: directions) {
            // 计算位置得分，优先考虑靠近棋子的点
            int positionScore = 0;
            ChessPoint point = nowPoint.getNext(direction, 1);
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] != Chess.EMPTY) {
                positionScore++;
            }
            point = nowPoint.getNext(direction, -1);
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] != Chess.EMPTY) {
                positionScore++;
            }
            if (positionScore > 0) {
                //System.out.println(direction.getName() + "的位置评分为" + positionScore);
            }
            totalScore += positionScore;
            // 先计算进攻分
            point = nowPoint.getNext(direction, 1);
            int chessCount = 0;
            int endCount = 0;
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess){
                point = point.getNext(direction, 1);
            }
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()){
                endCount++;
            }
            point = point.getNext(direction, -1);
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess){
                chessCount++;
                point = point.getNext(direction, -1);
            }
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()){
                endCount++;
            }
            int aScore = MoveScoreAttackType.matchScore(chessCount, endCount);
            if (aScore > 0) {
                //System.out.println(direction.getName() + "的进攻评分为" + aScore);
            }
            totalScore += aScore;
            //计算防守分
            int defChessCount = 0;
            int defEndCount = 0;
            int defType = 0;
            point = nowPoint.getNext(direction, 1);
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()) {
                defType++;
            }
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()){
                defChessCount++;
                point = point.getNext(direction, 1);
            }
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess) {
                defEndCount++;
            }
            point = nowPoint.getNext(direction, -1);
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()) {
                defType++;
            }
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess.getReverse()){
                defChessCount++;
                point = point.getNext(direction, -1);
            }
            if (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess) {
                defEndCount++;
            }
            int dScore = MoveScoreDefenseType.matchScore(defChessCount, defEndCount, defType);
            if (dScore > 0) {
                //System.out.println(direction.getName() + "的防守评分为" + dScore);
            }
            totalScore += dScore;
        }
        return totalScore;
    }

    /**
     * 复制一个棋盘。
     *
     * @param chessBoard 要复制的棋盘，是一个二维数组，其中每个元素代表棋盘上的一个位置。
     * @return 返回一个新的棋盘，它是输入棋盘的浅拷贝。如果输入棋盘为null，则返回null。
     *         注意：这里的浅拷贝意味着新棋盘中的每个元素都是对原始棋盘上对应元素的直接引用，
     *         而不是元素本身的拷贝。如果棋盘上的元素（即棋子）是可变的，则这种拷贝方式可能不会保留原始棋盘的状态。
     */
    public static Chess[][] copyChessBoard(Chess[][] chessBoard) {
        // 检查输入棋盘是否为null
        if (chessBoard == null) {
            return null;
        }

        // 创建一个新的二维数组来存储拷贝的棋盘
        Chess[][] newChessBoard = new Chess[BOARD_LINE][BOARD_LINE];

        // 遍历原始棋盘，并将每个棋子复制到新棋盘的对应位置
        for (int i = 0; i < BOARD_LINE; i++) {
            for (int j = 0; j < BOARD_LINE; j++) {
                newChessBoard[i][j] = chessBoard[i][j]; // 浅拷贝，直接引用原始棋子对象
            }
        }

        // 返回新拷贝的棋盘
        return newChessBoard;
    }

    /**
     * 下一手棋之后局面是不是终局
     * @param chessBoard
     * @param move
     * @param nowChess
     * @return
     */
    public static boolean isEnd(Chess[][] chessBoard, Move move, Chess nowChess) {
        ChessPoint thisPoint = new ChessPoint(move.getX(), move.getY());
        Direction[] directions = Direction.values();
        for (Direction direction: directions) {
            int count = 1;
            ChessPoint point = thisPoint.getNext(direction, 1);
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess) {
                count++;
                point.next(direction, 1);
            }
            point = thisPoint.getNext(direction, -1);
            while (point.isOnTable() && chessBoard[point.getX()][point.getY()] == nowChess) {
                count++;
                point.next(direction, -1);
            }
            if (count >= 5) {
                return true;
            }
        }
        return false;
    }



}
